/*
* Copyright (C) Microsoft. All rights reserved.  
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not 
* use this file except in compliance with the License.  You may obtain a copy 
* of the License at http://www.apache.org/licenses/LICENSE-2.0  
* 
* THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 
* WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
* MERCHANTABLITY OR NON-INFRINGEMENT. 
*
* See the Apache License, Version 2.0 for specific language governing 
* permissions and limitations under the License.
*
*/

#pragma once

#include <db/engines/jet/db_jet_types.h>
#include <memory.h>

namespace test_wrappers { namespace storage {

namespace b = test_wrappers;

#ifndef DB_TYPES
typedef unsigned long table_id;
typedef unsigned long field_id;
#endif

enum field_type
{
    type_unknown = 0,
    type_int16,
    type_int32,
    type_int64,
    type_float32,
    type_string_long,
    type_binaryBlob
};

enum db_errors
{
    e_db_duplilcate_index_name,
    e_db_unknown_index,
    e_db_instantiate_unknown_type,
    e_db_field_definition_id_not_found,
    e_db_field_instance_id_not_found,
    e_db_field_instance_not_found
};

struct binary_blob
{
    unsigned int _size;
    void* _buffer;

    void create(const unsigned int  size)
    {
        _size = size;
        if (_size != 0)
        {
            if (_buffer !=  nullptr)
            {
                delete [] _buffer;
            }
            _buffer = new char [_size];
        }
    }

    void createAndCopy(const unsigned int  size, const void* buffer)
    {
        create(size);
        if (_size != 0)
        {
            memcpy(_buffer, buffer, _size);
        }
    }

    void moveFrom(binary_blob& blob)
    {
        _size = blob._size;
        if (_buffer != nullptr)
        {
            delete [] _buffer;
        }
        _buffer = blob._buffer;

        blob._size = 0;
        blob._buffer = nullptr;
    }

    void operator=(const binary_blob& blob)
    {
        createAndCopy(blob._size, blob._buffer);
    }

    // constructors
    binary_blob() :
        _size(0),
        _buffer(nullptr)
    {
    }

    binary_blob(const binary_blob& blob) :
        _size(blob._size),
        _buffer(nullptr)
    {
        createAndCopy(blob._size, blob._buffer);
    }

    binary_blob(const unsigned int  size, const void* buffer) :
        _size(size),
        _buffer(nullptr)
    {
        createAndCopy(size, buffer);
    }

    binary_blob(const unsigned int size) :
        _size(size),
        _buffer(nullptr)
    {
        create(size);
    }

    // destructor
    ~binary_blob()
    {
        empty();
    }

    // free
    void empty()
    {
        if (_buffer != nullptr)
        {
            delete [] _buffer;
            _buffer = nullptr;
        }
        _size = 0;
    }
};

struct field_id_b
{
    field_id id;

    field_id_b() :
        id(0)
    {}

    field_id_b(field_id id_) :
        id(id_)
    {}
};

template <class T>
struct field_id_t :
    public field_id_b
{

    field_id_t() :
        field_id_b(0)
    {
    }

    field_id_t(field_id id_) :
        field_id_b(id_)
    {
    }
};

}} // namespace test_wrappers::storage
